package com.example.nio.util;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.nio.commons.Message;
import com.example.nio.entity.AppConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 与微信收发信息接口
 *
 * @author yongjiehuang
 * @date 2019年1月16日
 */
@Component
public class WxUtils {

    //测试请求次数
    static int i=0;
    public static Logger logger = LoggerFactory.getLogger(WxUtils.class);

    // 向微信发信息url
    private static final String toWxUrl = "https://api.weixin.qq.com/cgi-bin/message/custom/send";

    // 上传多媒体文件url
    private static final String uploadMediaUrl = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=@{token}&type=@{type}";

    // 下载多媒体文件url
    private static final String downMediaUrl = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=@{token}&media_id=@{id}";


    // 读取微信图片虚拟路径
    @Value("/showPicture/")
    public String fimagUrl;

    // 微信存音频url
    public static String voiceUrl;

    // 读取微信音频虚拟路径
    public static String fvoiceUrl;


//    @Value("${wx.voice}")
    public void setVoice(String voice) {
        WxUtils.voiceUrl = voice;
    }

//    @Value("${wx.fvoice}")
    public void setFvoice(String fvoice) {
        WxUtils.fvoiceUrl = fvoice;
    }

    private static final String gettoken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}";


    @Autowired
    private RestTemplate restTemplate;

    public String getToken(){
        String result = "";
        try {
            HttpHeaders header = new HttpHeaders();
            header.setContentType(MediaType.valueOf(MediaType.APPLICATION_XML_VALUE));
            header.setContentType(MediaType.APPLICATION_JSON);
            org.springframework.http.HttpEntity entity = new org.springframework.http.HttpEntity(header);
            String url = gettoken.replace("${APPID}", AppConfig.appId).replace("${APPSECRET}",AppConfig.secret);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, entity, String.class);
            JSONObject obj = JSONUtil.parseObj(responseEntity.getBody());
            result = (String) obj.get("access_token");
        }catch (Exception e){
            System.out.println("获取保网token失败" + e.getMessage());
        }
        return result;
    }
    /**
     * 发送信息给微信
     *
     * @param message
     */
  //  public static void sendToWx(Message message) {
    public void sendToWx(Message message) {
        try {
            String kefu = message.getFromUser();
            if(i!=0){
                i=0;
            }
            String accesstoken = getToken();
            if(StringUtils.isBlank(accesstoken)){
                logger.info("获取不了access_token");
                return;
            }
            logger.info(message.toString());
            // 拼接URL
            String url = toWxUrl + "?access_token=" + accesstoken;
            String touser = message.getToUser();
            String msgtype = "";
            String text = "";
            // 添加参数
            String sendjson = "";
            if (message.getMsgType() != null) {
                switch (message.getMsgType()) {
                    case "img":
                        String content = message.getContent();
                        String filename = content
                                .substring(content.lastIndexOf(fimagUrl) + fimagUrl.length());
                        String path = imagUrl + filename;
                        File file = new File(path);
                        msgtype = "image";
                        String id = Upload(msgtype, file,accesstoken);
                        text = "{\"media_id\":\"" + id + "\"}";
                        sendjson = "{\"touser\":\"" + touser + "\",\"msgtype\":\"" + msgtype + "\",\"image\":" + text + "}";
                        break;
                    case "3":
                        text = "{\"media_id\":\"" + message.getContent() + "\"}";
                        sendjson = "{\"touser\":\"" + touser + "\",\"msgtype\":\"" + msgtype + "\",\"voice\":" + text + "}";
                        break;
                    default:
                        msgtype = "text";
                        text = "{\"content\":\"" + message.getContent() + "\"}";
                        sendjson = "{\"touser\":\"" + touser + "\",\"msgtype\":\"" + msgtype + "\",\"text\":" + text + "}";
                        break;
                }
            } else {
                msgtype = "text";
                text = "{\"content\":\"" + message.getContent() + "\"}";
                sendjson = "{\"touser\":\"" + touser + "\",\"msgtype\":\"" + msgtype + "\",\"text\":" + text + "}";
            }
            HttpHeaders header = new HttpHeaders();
            header.setContentType(MediaType.APPLICATION_JSON);
            org.springframework.http.HttpEntity entity = new org.springframework.http.HttpEntity(sendjson, header);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, entity, String.class);
            // 获取结果实体
            String body = responseEntity.getBody();
            if (body != null) {
                SimpleDateFormat dateFormats = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                Date now=new Date();
                String nowstr=dateFormats.format(now);
                logger.info("("+")post请求"+nowstr+"获取token:"+accesstoken);
                logger.info(nowstr+"微信返回消息："+body);
                String resultCode = JSONUtil.parseObj(body).get("errcode").toString();
                if(resultCode.equals("40001") ){
                    sendToWx(message);
                }
            }

        } catch (Exception e) {
            logger.error("发送信息失败", e);
        }
    }





    /**
     * 上传媒体文件
     *
     * @param type
     * @return 媒体文件id
     * @throws IOException
     */
    public String Upload(String type, File file,String accesstoken) throws IOException {
        String url1 = uploadMediaUrl.replace("@{token}", accesstoken).replace("@{type}", type);
        URL url = new URL(url1);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        String result = null;
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setUseCaches(false); // post方式不能使用缓存
        // 设置请求头信息
        con.setRequestProperty("Connection", "Keep-Alive");
        con.setRequestProperty("Charset", "UTF-8");
        // 设置边界
        String BOUNDARY = "----------" + System.currentTimeMillis();
        con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
        StringBuilder sb = new StringBuilder();
        sb.append("--"); // 必须多两道线
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"\r\n");
        sb.append("Content-Type:application/octet-stream\r\n\r\n");

        byte[] head = sb.toString().getBytes("utf-8");
        OutputStream out = new DataOutputStream(con.getOutputStream());
        out.write(head);

        DataInputStream dataIn = new DataInputStream(new FileInputStream(file));
        int bytes = 0;
        byte[] bufferOut = new byte[1024];
        while ((bytes = dataIn.read(bufferOut)) != -1) {
            out.write(bufferOut, 0, bytes);
        }
        dataIn.close();

        byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
        out.write(foot);

        out.flush();
        out.close();

        StringBuffer buffer = new StringBuffer();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            if (result == null) {
                result = buffer.toString();
            }
        } catch (IOException e) {
            logger.error("发送POST请求出现异常！数据读取异常" + e);
        } finally {
            if (reader != null) {
                reader.close();
            }

        }
        String str = buffer.toString();
        result = (String) JSONUtil.parseObj(str).get("media_id");
        return result;
    }

    /**
     * 下载微信多媒体并获得url
     *
     * @param id         媒体id
     * @param type       媒体类型
     * @return 多媒体访问路径
     */
    public String down(String id, String type, String accesstoken) {
        try {
            File pfile = new File(WxUtils.voiceUrl);
            if (!pfile.exists()) {
                pfile.mkdirs();
            }
            String result = "";
            CloseableHttpClient httpClient = HttpClients.createDefault();
            String url = downMediaUrl.replace("@{token}", getToken());
            url = url.replace("@{id}", id);
            HttpGet get = new HttpGet(url);
            // 设置表头
            get.setHeader("Content-type", "application/json;charset=utf-8");
            get.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            CloseableHttpResponse response = httpClient.execute(get); // 获取结果实体
            HttpEntity entity = response.getEntity();
            ContentType contentType = ContentType.get(entity);
            String firstPath = UUID.randomUUID().toString().replaceAll("-", "") + ".";
            String Path = firstPath;
            String targetPath = WxUtils.voiceUrl + Path + contentType.getMimeType().split("/")[1];
            result = WxUtils.fvoiceUrl + Path + "mp3";
            // 写入磁盘
            InputStream in = entity.getContent();
            OutputStream os = null;
            try {
                File file = new File(targetPath);
                if (file.exists()) {
                    file.delete();
                }
                file.createNewFile();
                os = new FileOutputStream(file);
                int len = 0;
                byte[] ch = new byte[1024];
                while ((len = in.read(ch)) != -1) {
                    os.write(ch, 0, len);
                }
                String mp3Path = WxUtils.voiceUrl + Path + "mp3";
                File target = new File(mp3Path);
                target.createNewFile();
//                AudioAttributes audio = new AudioAttributes();
//                audio.setCodec("libmp3lame");
//                EncodingAttributes attrs = new EncodingAttributes();
//                attrs.setFormat("mp3");
//                attrs.setAudioAttributes(audio);
//                Encoder encoder = new Encoder();
//                MultimediaObject multimediaObject = new MultimediaObject(file);
//                encoder.encode(multimediaObject, target, attrs);
            } catch (IOException e) {
                logger.error("下载音频文件失败", e);
                return "error";
            } finally {
                os.close();
            }
            return result;
        } catch (Exception e) {
            logger.error("上传media失败", e);
            return "error";
        }
    }

    // 微信存图片url
    @Value("${wx.imag}")
    private String imagUrl;

    public String doImgUpload(String fileUrl,String fileName) {
        // 获取文件后缀
        fileName = fileName + ".jpg";
        File dofile = new File(imagUrl + fileName);
        try {
            if (dofile.exists()) {
                dofile.delete();
            }
            dofile.createNewFile();
            FileOutputStream inputStream = new FileOutputStream(dofile);
            URL url = new URL(fileUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){
                FileCopyUtils.copy(connection.getInputStream(),inputStream);

            }
        }catch (IOException e){
            System.out.println("IO异常");
        }
        return "/showPicture/" + fileName;
    }

}
